// TODO переписать на гот по возможности
import fetch from "cross-fetch";
import { APIError } from "puregram";
import { ErrorCodes } from "../exports/errorCodes";
import message from "../middlewares/message";

interface JmacApiResponse {
    result?: any;
    error?: string;
}

interface JmacApiOptions {
    secret: string;
    client: string;
}

class JmacApiError extends Error {
    message: string;
    code: number;
    result = false;
    constructor(message, code) {
        super(message);
        this.message = message;
        this.code = code;
    }
}

export class JmacApi {
    private _client: string;
    private _secret: string;
    private _BASE_URL = process.env.BASE_URL;

    constructor(options: JmacApiOptions) {
        this._client = options.client;
        this._secret = options.secret;
    }

    ping = async () => {
        try {
            const controller = new AbortController();
            const timeoutId = setTimeout(() => controller.abort(), 5000);
            const response = await fetch(`${this._BASE_URL}/api/server/ping`, {
                signal: controller.signal,
            });
            clearTimeout(timeoutId);
            if (!response.ok)
                return new JmacApiError(response.statusText, response.status);
            return { result: true };
        } catch (e) {
            console.log(e);
            return {
                result: false,
                message: e.message,
                code: e.code || "ETIMEDOUT",
            };
        }
    };
    private _check_json = (json) => {
        try {
            JSON.parse(json);
            return true;
        } catch (e) {
            return false;
        }
    };

    private _parse_response = (response: string) => {
        // FIXME!!!
        // а вообще, лучше сделай проверку жсона ниже, в _request
        // if (!this._check_json(response))
        //     return { error: ErrorCodes.SERVER_INVALID_RESPONSE };
        return response["error"]
            ? new JmacApiError(response["error"], -1) // TODO
            : response["result"];
    };

    private _request = async (section, method, params) => {
        (params.secret = this._secret), (params.client = this._client);

        const url = new URL(`${this._BASE_URL}/api/${section}/${method}`);
        url.search = new URLSearchParams(params).toString();
        console.log(url.toString());

        return this._parse_response(
            // @ts-ignore
            await fetch(url.toString(), {
                method: "get",
            }).then((r) => r.json())
        );
    };

    commands = {
        text: {
            joke: {
                handler: (params = {}) =>
                    this._request("text", "randomAnekdot", params),
            },
        },
    };
}
